package com.onesports.intelligent.k12.polarlight.service.course;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.onesports.framework.kit.common.util.ParamUtils;
import com.onesports.intelligent.k12.polarlight.common.errors.exceptions.BusinessException;
import com.onesports.intelligent.k12.polarlight.domain.dto.cls.ClassPageDTO;
import com.onesports.intelligent.k12.polarlight.domain.dto.course.CourseScheduleTemplateDTO;
import com.onesports.intelligent.k12.polarlight.domain.entity.course.CourseOpen;
import com.onesports.intelligent.k12.polarlight.domain.entity.course.CourseScheduleTemplate;
import com.onesports.intelligent.k12.polarlight.domain.entity.organization.CoachScheduleTemplateRel;
import com.onesports.intelligent.k12.polarlight.domain.entity.sys.Dict;
import com.onesports.intelligent.k12.polarlight.domain.vo.cls.ClassPageVO;
import com.onesports.intelligent.k12.polarlight.domain.vo.course.CourseScheduleTemplateVO;
import com.onesports.intelligent.k12.polarlight.domain.vo.course.TemplateVO;
import com.onesports.intelligent.k12.polarlight.mapper.course.ClassInfoMapper;
import com.onesports.intelligent.k12.polarlight.mapper.course.CourseOpenMapper;
import com.onesports.intelligent.k12.polarlight.mapper.course.CourseScheduleTemplateMapper;
import com.onesports.intelligent.k12.polarlight.mapper.organization.CoachScheduleTemplateRelMapper;
import com.onesports.intelligent.k12.polarlight.service.sys.SysDictService;
import com.onesports.intelligent.k12.polarlight.util.BeanCopyUtil;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Wsy
 **/
@Service
@RequiredArgsConstructor
public class CourseScheduleTemplateService extends ServiceImpl<CourseScheduleTemplateMapper, CourseScheduleTemplate> {

    private final SysDictService sysDictService;

    private final CourseScheduleTemplateMapper mapper;

    private final CoachScheduleTemplateRelMapper coachScheduleTemplateRelMapper;

    private final CourseOpenMapper courseOpenMapper;

    /**
     * 上课时段列表
     *
     * @return List<CourseScheduleTemplateVO>
     */
    public List<String> scheduleTemplate() {
        List<String> resultDate = new ArrayList<String>();
        List<CourseScheduleTemplate> list = list(new LambdaQueryWrapper<CourseScheduleTemplate>()
                .orderByAsc(CourseScheduleTemplate::getStartTime)
                .orderByAsc(CourseScheduleTemplate::getEndTime));
        List<CourseScheduleTemplateVO> courseScheduleTemplateVOS = BeanCopyUtil.copyListProperties(list, CourseScheduleTemplateVO::new);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm");
        courseScheduleTemplateVOS.forEach(i -> {
            String result = "";
            result = simpleDateFormat.format(i.getStartTime()) + " - " + simpleDateFormat.format(i.getEndTime());
            resultDate.add(result);
        });
        return resultDate;
    }

    /**
     * 保存修改通用方法
     *
     * @param courseScheduleTemplateDTO
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveOrUpdateDetail(CourseScheduleTemplateDTO courseScheduleTemplateDTO) {

        CourseScheduleTemplateDTO dto = checkId(courseScheduleTemplateDTO);
        if(StringUtils.isNotEmpty(dto.getId())){
            checkTimeByCoach(dto.getId());
        }
        CourseScheduleTemplate entity = new CourseScheduleTemplate();
        BeanUtils.copyProperties(dto, entity);
        if (dto.getStartTime().compareTo(dto.getEndTime()) == 1 || dto.getStartTime().equals(dto.getEndTime())) {
            throw new BusinessException("开始时间不可以大于结束时间且时间不能相等");
        }
        checkDate(dto);
        checkName(dto);
        return saveOrUpdate(entity);
    }

//    /**
//     * 如果该节次被使用过无法删除或者修改
//     * @param startDate
//     * @param endDate
//     */
//    void checkTime(Date startDate,Date endDate){
//        ClassPageDTO classPageDTO = new ClassPageDTO();
//        classPageDTO.setDateStart(startDate);
//        classPageDTO.setDateEnd(endDate);
//        IPage<ClassPageVO> classDetail = classInfoMapper.getClassDetail(new Page<>(1, Long.MAX_VALUE), classPageDTO, null);
//        if (CollectionUtils.isNotEmpty(classDetail.getRecords())){
//            throw new BusinessException("该节次已经正式使用，无法编辑/删除");
//        }
//    }

    /**
     * 根据订单ID检查
     * @param id
     */
    void checkTimeByCoach(String id){
        List<CoachScheduleTemplateRel> coachScheduleTemplateRels = coachScheduleTemplateRelMapper.selectList(new LambdaQueryWrapper<CoachScheduleTemplateRel>()
                .eq(CoachScheduleTemplateRel::getScheduleTemplateId, id));
        List<CourseOpen> courseOpens = courseOpenMapper.selectList(new LambdaQueryWrapper<CourseOpen>().eq(CourseOpen::getScheduleTemplateId, id));

        if(!coachScheduleTemplateRels.isEmpty() || !courseOpens.isEmpty()){
            throw new BusinessException("该节次已经正式使用，无法编辑/删除");
        }
    }

    /**
     * 时间是否重复
     *
     * @param dto
     */
    public void checkDate(CourseScheduleTemplateDTO dto) {
        List<CourseScheduleTemplate> listDate = list(new LambdaQueryWrapper<CourseScheduleTemplate>()
                .eq(CourseScheduleTemplate::getStartTime, dto.getStartTime()).or()
                .eq(CourseScheduleTemplate::getEndTime, dto.getEndTime()));
        if (StringUtils.isEmpty(dto.getId())) {
            if (CollectionUtils.isNotEmpty(listDate)) {
                throw new BusinessException("时间重复");
            }
        } else {
            List<String> collect = listDate.stream().map(CourseScheduleTemplate::getId).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collect)) {
                if (collect.size() == 1) {
                    if (!dto.getId().equals(collect.stream().findFirst().orElse(null))) {
                        throw new BusinessException("时间重复");
                    }
                } else {
                    throw new BusinessException("时间重复");
                }
            }
        }
    }

    /**
     * 校验名称
     *
     * @param dto
     */
    public void checkName(CourseScheduleTemplateDTO dto) {
        List<CourseScheduleTemplate> list = list(new LambdaQueryWrapper<CourseScheduleTemplate>()
                .eq(CourseScheduleTemplate::getSectionCode, dto.getSectionCode()));
        if (StringUtils.isEmpty(dto.getId())) {
            if (CollectionUtils.isNotEmpty(list)) {
                throw new BusinessException("名称重复");
            }
        } else {
            if (CollectionUtils.isNotEmpty(list)) {
                if (list.size() != 1) {
                    throw new BusinessException("名称重复");
                }
                CourseScheduleTemplate courseScheduleTemplate = list.stream().findFirst().orElse(null);
                if (!courseScheduleTemplate.getId().equals(dto.getId())) {
                    throw new BusinessException("名称重复");
                }
            }
        }

    }


    /**
     * 校验ID，并且返回正确的数据
     *
     * @return
     */
    public CourseScheduleTemplateDTO checkId(CourseScheduleTemplateDTO dto) {
        if (StringUtils.isNotEmpty(dto.getId())) {
            Optional.ofNullable(getById(dto.getId())).orElseThrow(() -> new BusinessException("模板编号不存在"));
        }
        return dto;
    }

    /**
     * 删除排版模板
     *
     * @param id
     * @return
     */
    public Boolean deleteById(String id) {
        CourseScheduleTemplate byId = getById(id);
        if (byId!=null){
            checkTimeByCoach(id);
        }
        return removeById(id);
    }

    /**
     * 分页查询
     *
     * @param page
     * @param size
     * @return
     */
    public IPage<CourseScheduleTemplateVO> getPageDetail(Long page, Long size) {
        Page<CourseScheduleTemplate> courseScheduleTemplatePage = new Page<>(page, size);
        Page<CourseScheduleTemplateVO> resultPage = new Page<>(page, size);
        Page<CourseScheduleTemplate> page1 = this.page(courseScheduleTemplatePage, new LambdaQueryWrapper<CourseScheduleTemplate>()
                        .orderByAsc(CourseScheduleTemplate::getSectionCode)
                .orderByAsc(CourseScheduleTemplate::getStartTime)
                .orderByAsc(CourseScheduleTemplate::getEndTime));
        BeanUtils.copyProperties(page1, resultPage, "records");
        List<CourseScheduleTemplateVO> courseScheduleTemplateVOS = BeanCopyUtil.copyListProperties(page1.getRecords(), CourseScheduleTemplateVO::new);
        //取字典
        List<Dict> dictList = sysDictService.getByCode();
        courseScheduleTemplateVOS.forEach(i -> {
            String name = dictList.stream()
                    .filter(j -> j.getCode().equals(i.getSectionCode())).map(Dict::getName)
                    .findFirst().orElse(null);
            i.setSectionName(name);
        });
        resultPage.setRecords(courseScheduleTemplateVOS);
        return resultPage;
    }


    /**
     * 获取没有分页的list
     *
     * @return List<CourseScheduleTemplateVO>
     */
    public List<CourseScheduleTemplateVO> courseScheduleTemplate() {
        List<CourseScheduleTemplate> courseScheduleTemplates = this.mapper.selectList(null);
        if (ParamUtils.isEmpty(courseScheduleTemplates)){
            return new ArrayList<>();
        }
        //取字典
        Map<String, String> sectionMap = sysDictService.getByCode().stream().collect(Collectors.toMap(Dict::getCode, Dict::getName));

        return courseScheduleTemplates.stream().map(i->{
            CourseScheduleTemplateVO courseScheduleTemplateVO = com.onesports.framework.kit.common.util.BeanUtils.copyProperties(i, CourseScheduleTemplateVO.class);
            courseScheduleTemplateVO.setSectionName(sectionMap!= null && ParamUtils.isNotEmpty(sectionMap.get(i.getSectionCode())) ? sectionMap.get(i.getSectionCode()) : "");
            return courseScheduleTemplateVO;
        }).collect(Collectors.toList());
    }

    /**
     * function：查看所有节次信息，包含开始时间结束时间
     *
     * @param
     * @return List<TemplateVO> 节次模板表
     * @author wangcx
     * @since 2022/7/28 10:10
     */
    public List<TemplateVO> getTemplate() {
        return this.mapper.getTemplate();
    }
}
